package models

import (
	"gorm.io/gorm"
	"huijing_mall/variable"

	"time"
)

// User 用户表
type User struct {
	BaseModel // 包含ID、CreatedAt、UpdatedAt等基础字段

	// 基本信息
	Username string  `gorm:"size:30;not null;uniqueIndex;comment:登录账号" json:"username"`
	Password string  `gorm:"size:100;not null;comment:加密密码" json:"password"` // 密码不返回前端
	Nickname string  `gorm:"size:50;not null;comment:昵称" json:"nickname"`
	Avatar   string  `gorm:"size:255;comment:头像URL" json:"avatar"`
	Mobile   *string `gorm:"size:20;uniqueIndex;comment:手机号" json:"mobile,omitempty"`
	Email    *string `gorm:"size:50;uniqueIndex;comment:邮箱" json:"email,omitempty"`

	// 权限相关（核心简化：直接用字段区分角色，无需单独Role表）
	RoleType string `gorm:"type:enum('user','admin');default:'user';comment:角色类型(user-普通用户,admin-管理员)" json:"role_type"`

	// 父子账号关系（核心：通过ParentID关联上级用户）
	ParentID *uint  `gorm:"comment:上级用户ID(为空则是顶级账号)" json:"parent_id,omitempty"`
	Parent   *User  `gorm:"foreignKey:ParentID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"parent,omitempty"` // 上级账号
	Children []User `gorm:"foreignKey:ParentID" json:"children,omitempty"`                                             // 下级账号（子账号）

	// 其他业务字段（保留必要的）
	AuthStatus   variable.AuthStatus `gorm:"type:enum('verified','unverified');default:'unverified';comment:认证状态" json:"auth_status"`
	Balance      float64             `gorm:"type:decimal(12,2);default:0;comment:账户余额" json:"balance"`
	Integral     float64             `gorm:"type:decimal(12,2);default:0;comment:积分" json:"integral"`
	Status       bool                `gorm:"default:true;comment:账号状态(true-正常,false-禁用)" json:"status"`
	LastLoginAt  *time.Time          `gorm:"comment:最后登录时间" json:"last_login_at"`
	RegisterDays int                 `gorm:"-;comment:注册天数(计算字段)" json:"register_days"`
}

// Create 实现ModelCRUD接口的Create方法
func (u *User) Create(db *gorm.DB) error {
	return db.Create(u).Error
}

// Update 实现ModelCRUD接口的Update方法
func (u *User) Update(db *gorm.DB) error {
	return db.Model(u).Updates(u).Error // 注意：需确保u.ID已赋值
}

// Delete 实现ModelCRUD接口的Delete方法
func (u *User) Delete(db *gorm.DB, id uint) error {
	return db.Delete(&User{}, id).Error
}

// GetByID 实现ModelCRUD接口的GetByID方法
func (u *User) GetByID(db *gorm.DB, id uint) error {
	return db.First(u, id).Error
}

// GetByID 实现ModelCRUD 根据某个字段查询记录
func (u *User) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(u)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// List 实现ModelCRUD接口的List方法
func (u *User) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var users []User

	// 计算总数
	if err := db.Model(&User{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * pageSize
	if err := db.Offset(offset).Limit(pageSize).Find(&users).Error; err != nil {
		return nil, 0, err
	}

	// 转换为[]interface{}（接口要求的返回类型）
	result := make([]interface{}, len(users))
	for i, v := range users {
		result[i] = v
	}
	return result, total, nil
}

// GetByID 实现ModelCRUD 根据某个字段查询记录
func (u *User) FindByRawSQL(db *gorm.DB, query string, args ...interface{}) error {
	result := db.Raw(query, args...).Scan(u)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return gorm.ErrRecordNotFound
	}
	return nil
}

// UserAvatarHistory 用户头像历史
type UserAvatarHistory struct {
	BaseModel
	UserID    uint   `gorm:"not null;index;comment:关联用户ID" json:"user_id"`
	AvatarURL string `gorm:"size:255;not null;comment:头像URL" json:"avatar_url"`
	IsCurrent bool   `gorm:"default:false;comment:是否当前头像" json:"is_current"`

	// 关联关系
	User User `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
}

func (u *UserAvatarHistory) FindByRawSQL(db *gorm.DB, query string, args ...interface{}) error {
	result := db.Raw(query, args...).Scan(u)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return gorm.ErrRecordNotFound
	}
	return nil
}

func (u *UserAvatarHistory) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(u)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// UserAvatarHistory 实现
func (u *UserAvatarHistory) Create(db *gorm.DB) error {
	return db.Create(u).Error
}

func (u *UserAvatarHistory) Update(db *gorm.DB) error {
	return db.Model(u).Updates(u).Error
}

func (u *UserAvatarHistory) Delete(db *gorm.DB, id uint) error {
	return db.Delete(&UserAvatarHistory{}, id).Error
}

func (u *UserAvatarHistory) GetByID(db *gorm.DB, id uint) error {
	return db.First(u, id).Error
}

func (u *UserAvatarHistory) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var histories []UserAvatarHistory

	if err := db.Model(&UserAvatarHistory{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	if err := db.Offset(offset).Limit(pageSize).Find(&histories).Error; err != nil {
		return nil, 0, err
	}

	result := make([]interface{}, len(histories))
	for i, v := range histories {
		result[i] = v
	}
	return result, total, nil
}

// Role 角色模型
type Role struct {
	BaseModel
	Name        string `gorm:"size:20;not null;uniqueIndex;comment:角色名称" json:"name"`
	Description string `gorm:"size:100;comment:角色描述" json:"description"`

	UserRole   []UserRole   `gorm:"foreignKey:ID;comment:拥有该角色的用户" json:"users,omitempty"`
	Permission []Permission `gorm:"foreignKey:ID;comment:角色拥有的权限" json:"permissions,omitempty"`
}

func (r *Role) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(r)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

func (r *Role) Create(db *gorm.DB) error {
	return db.Create(r).Error
}

func (r *Role) Update(db *gorm.DB) error {
	return db.Model(r).Updates(r).Error
}

func (r *Role) Delete(db *gorm.DB, id uint) error {
	return db.Delete(&Role{}, id).Error
}

func (r *Role) GetByID(db *gorm.DB, id uint) error {
	return db.Preload("Permissions").First(r, id).Error
}

func (r *Role) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var roles []Role

	if err := db.Model(&Role{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	if err := db.Offset(offset).Limit(pageSize).Preload("Permissions").Find(&roles).Error; err != nil {
		return nil, 0, err
	}

	result := make([]interface{}, len(roles))
	for i, v := range roles {
		result[i] = v
	}
	return result, total, nil
}

// UserRole 用户角色关联表
type UserRole struct {
	UserID uint `gorm:"primaryKey;comment:用户ID" json:"user_id"`
	RoleID uint `gorm:"primaryKey;comment:角色ID" json:"role_id"`

	// 关联关系
	User User `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;comment:关联用户" json:"-"`
	Role Role `gorm:"foreignKey:RoleID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;comment:关联角色" json:"-"`
}

func (ur *UserRole) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(ur)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

func (ur *UserRole) Create(db *gorm.DB) error {
	return db.Create(ur).Error
}

func (ur *UserRole) Update(db *gorm.DB) error {
	return db.Model(ur).Updates(ur).Error
}

func (ur *UserRole) Delete(db *gorm.DB, id uint) error {
	// 注意: UserRole使用复合主键，这里的id参数实际可能是userID，需要根据实际情况调整
	// 或者修改接口以支持复合主键删除
	return db.Where("user_id = ?", id).Delete(&UserRole{}).Error
}

func (ur *UserRole) GetByID(db *gorm.DB, id uint) error {
	// 注意: 这里的id参数实际可能是userID，需要根据实际情况调整
	return db.Where("user_id = ?", id).First(ur).Error
}

func (ur *UserRole) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var userRoles []UserRole

	if err := db.Model(&UserRole{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	if err := db.Offset(offset).Limit(pageSize).Find(&userRoles).Error; err != nil {
		return nil, 0, err
	}

	result := make([]interface{}, len(userRoles))
	for i, v := range userRoles {
		result[i] = v
	}
	return result, total, nil
}

// Permission 权限模型
type Permission struct {
	BaseModel
	Name     string `gorm:"size:50;not null;comment:权限名称" json:"name"`
	Code     string `gorm:"size:50;not null;uniqueIndex;comment:权限编码(如sys:user:add)" json:"code"`
	Type     int    `gorm:"not null;comment:权限类型(1-菜单,2-按钮,3-API)" json:"type"`
	ParentID int    `gorm:"default:0;comment:父权限ID" json:"parent_id"`
	Path     string `gorm:"size:200;comment:菜单路径" json:"path"`
	Icon     string `gorm:"size:50;comment:图标" json:"icon"`
	Sort     int    `gorm:"default:0;comment:排序" json:"sort"`

	Role []Role `gorm:"foreignKey:id;comment:拥有该权限的角色" json:"roles,omitempty"`
}

func (p *Permission) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(p)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// Permission 实现
func (p *Permission) Create(db *gorm.DB) error {
	return db.Create(p).Error
}

func (p *Permission) Update(db *gorm.DB) error {
	return db.Model(p).Updates(p).Error
}

func (p *Permission) Delete(db *gorm.DB, id uint) error {
	return db.Delete(&Permission{}, id).Error
}

func (p *Permission) GetByID(db *gorm.DB, id uint) error {
	return db.First(p, id).Error
}

func (p *Permission) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var permissions []Permission

	if err := db.Model(&Permission{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	if err := db.Offset(offset).Limit(pageSize).Find(&permissions).Error; err != nil {
		return nil, 0, err
	}

	result := make([]interface{}, len(permissions))
	for i, v := range permissions {
		result[i] = v
	}
	return result, total, nil
}

// RolePermission 角色权限关联表
type RolePermission struct {
	RoleID       uint      `gorm:"primaryKey;comment:角色ID" json:"role_id"`
	PermissionID uint      `gorm:"primaryKey;comment:权限ID" json:"permission_id"`
	CreatedAt    time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`

	// 关联关系
	Role       Role       `gorm:"foreignKey:RoleID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;comment:关联角色" json:"-"`
	Permission Permission `gorm:"foreignKey:PermissionID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;comment:关联权限" json:"-"`
}

func (rp *RolePermission) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(rp)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// RolePermission 实现
func (rp *RolePermission) Create(db *gorm.DB) error {
	return db.Create(rp).Error
}

func (rp *RolePermission) Update(db *gorm.DB) error {
	return db.Model(rp).Updates(rp).Error
}

func (rp *RolePermission) Delete(db *gorm.DB, id uint) error {
	// 注意: 使用role_id作为删除条件，根据实际情况调整
	return db.Where("role_id = ?", id).Delete(&RolePermission{}).Error
}

func (rp *RolePermission) GetByID(db *gorm.DB, id uint) error {
	// 注意: 使用role_id作为查询条件，根据实际情况调整
	return db.Where("role_id = ?", id).First(rp).Error
}

func (rp *RolePermission) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var rolePermissions []RolePermission

	if err := db.Model(&RolePermission{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	if err := db.Offset(offset).Limit(pageSize).Find(&rolePermissions).Error; err != nil {
		return nil, 0, err
	}

	result := make([]interface{}, len(rolePermissions))
	for i, v := range rolePermissions {
		result[i] = v
	}
	return result, total, nil
}

// UserAddress 用户地址
type UserAddress struct {
	BaseModel
	UserID    uint   `gorm:"not null;index;comment:用户ID" json:"user_id"`
	Receiver  string `gorm:"size:50;not null;comment:收货人" json:"receiver"`
	Phone     string `gorm:"size:20;not null;comment:联系电话" json:"phone"`
	Province  string `gorm:"size:50;not null;comment:省" json:"province"`
	City      string `gorm:"size:50;not null;comment:市" json:"city"`
	District  string `gorm:"size:50;not null;comment:区(县)" json:"district"`
	Detail    string `gorm:"size:200;not null;comment:详细地址" json:"detail"`
	IsDefault bool   `gorm:"default:false;comment:是否默认" json:"is_default"`

	// 关联关系
	User User `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
}

func (ua *UserAddress) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(ua)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

func (ua *UserAddress) FindByRawSQL(db *gorm.DB, query string, args ...interface{}) error {
	result := db.Raw(query, args...).Scan(ua)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return gorm.ErrRecordNotFound
	}
	return nil
}

// UserAddress 实现
func (ua *UserAddress) Create(db *gorm.DB) error {
	// 创建新地址时，如果设为默认地址，需要将同一用户的其他地址设为非默认
	if ua.IsDefault {
		if err := db.Model(&UserAddress{}).
			Where("user_id = ?", ua.UserID).
			Update("is_default", false).Error; err != nil {
			return err
		}
	}
	return db.Create(ua).Error
}

func (ua *UserAddress) Update(db *gorm.DB) error {
	// 更新为默认地址时，需要将同一用户的其他地址设为非默认
	if ua.IsDefault {
		if err := db.Model(&UserAddress{}).
			Where("user_id = ? AND id != ?", ua.UserID, ua.ID).
			Update("is_default", false).Error; err != nil {
			return err
		}
	}
	return db.Model(ua).Updates(ua).Error
}

func (ua *UserAddress) Delete(db *gorm.DB, id uint) error {
	return db.Delete(&UserAddress{}, id).Error
}

func (ua *UserAddress) GetByID(db *gorm.DB, id uint) error {
	return db.First(ua, id).Error
}

func (ua *UserAddress) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var addresses []UserAddress

	// 如果指定了用户ID，只查询该用户的地址
	query := db.Model(&UserAddress{})
	if ua.UserID > 0 {
		query = query.Where("user_id = ?", ua.UserID)
	}

	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	resultQuery := query.Offset(offset).Limit(pageSize)
	if ua.UserID > 0 {
		resultQuery = resultQuery.Where("user_id = ?", ua.UserID)
	}

	if err := resultQuery.Find(&addresses).Error; err != nil {
		return nil, 0, err
	}

	result := make([]interface{}, len(addresses))
	for i, v := range addresses {
		result[i] = v
	}
	return result, total, nil
}
